package com.wenge.datagroup.storage.util

import com.alibaba.fastjson.JSONObject
import com.wenge.datagroup.storage.dataprocess.{MultilingualLanguage, MultilingualTranslation}

import java.util.concurrent.ConcurrentHashMap

import scala.reflect.runtime.{universe => ru}
import scala.util.{Failure, Success, Try}

/**
 * @author
 *   Depp
 */
class MethodMatch {

  def transformMethodMatch(
      methodName: String,
      druidDataSource: DruidDataSource,
      multilingualLanguage: MultilingualLanguage,
      multilingualTranslation: MultilingualTranslation,
      orgRecord: JSONObject,
      map: ConcurrentHashMap[String, Any],
      orgField: String,
      finalField: String,
      preValue: String): Any = {
    var invoke: Any = null
    Try {
      val constructor: ru.MethodSymbol =
        ru.typeOf[TransformUtil].decl(ru.termNames.CONSTRUCTOR).asMethod
      val clazz: ru.ClassSymbol = ru.typeOf[TransformUtil].typeSymbol.asClass
      val mirror: ru.Mirror = ru.runtimeMirror(getClass.getClassLoader)
      val classMirror: ru.ClassMirror = mirror.reflectClass(clazz)
      val methodMirror: ru.MethodMirror = classMirror.reflectConstructor(constructor)
      val o: Any = methodMirror(druidDataSource, multilingualLanguage, multilingualTranslation)
      val instanceMirror = mirror.reflect(o)
      var method: ru.MethodSymbol = null
      methodName match {
        case "md5Hex" | "getLang" | "otherString" | "otherBoolean" | "emoExtract" =>
          method = ru.typeOf[TransformUtil].decl(ru.TermName(methodName)).asMethod
          invoke = instanceMirror.reflectMethod(method)(orgRecord, orgField)
        case "concat" =>
          method = ru.typeOf[TransformUtil].decl(ru.TermName(methodName)).asMethod
          invoke = instanceMirror.reflectMethod(method)(orgRecord, orgField, preValue)
        case "concatApp" =>
          method = ru.typeOf[TransformUtil].decl(ru.TermName(methodName)).asMethod
          invoke = instanceMirror.reflectMethod(method)(orgRecord, map, preValue)
        case "keywordsExtract" | "getIsnNew"| "getAlexaInfo" =>
          method = ru.typeOf[TransformUtil].decl(ru.TermName(methodName)).asMethod
          invoke = instanceMirror.reflectMethod(method)(orgRecord, map, orgField)
        case "entityExtract" | "translationProcess" | "autoAbstractProcess" | "wikiTranslationProcess" =>
          method = ru.typeOf[TransformUtil].decl(ru.TermName(methodName)).asMethod
          invoke = instanceMirror.reflectMethod(method)(orgRecord, map, orgField, finalField)
        case "splitWordProcess" | "mappingMegType" | "extractHost" =>
          method = ru.typeOf[TransformUtil].decl(ru.TermName(methodName)).asMethod
          invoke = instanceMirror.reflectMethod(method)(orgRecord, orgField, finalField)
        case _ =>
      }
      invoke
    } match {
      case Success(invoke) => invoke
      case Failure(e) =>
        println(s"invoke method args error, check the args, methodName: $methodName\n $e")
    }
  }
}
